/********************************************************************************
 ***                                                                          *** 
 ********************************************************************************
 *                                                                              * 
 *           Prject Name : MEMORIA                                              * 
 *                                                                              * 
 *             File Name : wordline.cpp                                         * 
 *                                                                              * 
 *            Programmer : LBW                                                  * 
 *                                                                              * 
 *            Start Date : 2020/12/26                                           * 
 *                                                                              * 
 *           Last Update : 2020/12/26  [LBW]                                    * 
 *                                                                              * 
 *------------------------------------------------------------------------------*
 * Functions:                                                                   * 
 *   WordLine::WordLine -- 构造测试用卡片的选项行                               * 
 *   WordLine::getRandomOrder -- 产生一个随机数组用于打乱nails[]的顺序          * 
 *   WordLine::paintEvent -- Qt中改变部件样式需要定义的事件                     *
 *   WordLine::nailAt -- 返回一个指向指定nail的指针                             *
 *   WordLine::getNumOfNails -- 返回需要记忆的单词+干扰词的数量                 *
 *==============================================================================*/

#include <QtWidgets>
#include <QStringList>
#include <QVector>
#include <QtGlobal>
#include <QSqlDatabase>
#include <QSqlQuery>
#include <QSqlError>

#include "wordline.h"
#include "nail.h"
#include "flowlayout.h"

/**********************************************************************************
 * WordLine::WordLine -- 构造测试用卡片的选项行                                   *
 *                                                                                *
 *   从strAnswer提取出来的单词为需要记忆的单词                                    *
 *   从strInterference提取出来的是干扰词                                          *
 *   用这些词去构造Nail,再随机排列Nail，就形成了选项行                            *
 *                                                                                *
 * INPUT: strAnswer -- 需要记忆的外语句子                                         *
 *        vWordPos -- 单词的起始位置                                              *
 *        vWordLength -- 单词的长度                                               *
 *        strInterference -- 干扰信息                                             *
 *        randomEnable -- 随机使能标志                                            *
 *        parent -- WorlLine的父对象                                              *
 *                                                                                *
 * OUTPUT: numOfWords -- 需要记忆的单词的数量                                     *
 *                                                                                *
 * WARNINGS: none                                                                 *
 *                                                                                *
 * HISTORY:                                                                       *
 *   2020/12/26 LBW : Created.                                                    *
 *================================================================================*/

WordLine::WordLine(QString strAnswer,QVector<int> vWordPos,QVector<int> vWordLength,QString strInterference,bool randomEnable,QWidget *parent):QWidget(parent)
{
	wordPos = vWordPos;
	wordLength = vWordLength;
	QString word;

	//干扰词不为空且有效单词不为0时才显示干扰词
	if(strInterference != "" && wordPos.size() > 0){
		wordList = strInterference.split("=");
		numOfNails = wordPos.size() + (wordList.size()>10?10:wordList.size());
	}else{
		numOfNails = wordPos.size();
	}	

	//输入检测，如果单词+干扰词的数量>25要报错
	if(numOfNails>25){
		qDebug() << "too many words";
		numOfNails = 25;
	}

	order.resize(numOfNails);

	//构造Nail
	FlowLayout *nailLayout = new FlowLayout;
	nailLayout->setAlignment(Qt::AlignLeft |Qt::AlignTop);
	for(int i=0;i<wordPos.size();i++){
		word = strAnswer.mid(wordPos[i],wordLength[i]);
		nails[i] = new Nail(word,this);
		nails[i]->setId(i);
	}
	
	//添加干扰词
	if(strInterference != "" && wordPos.size() > 0){
		for(int i=0;i<(numOfNails-wordPos.size());i++){
			word = wordList.at(i);
			nails[i+wordPos.size()] = new Nail(word,this);
			nails[i+wordPos.size()]->setId(i+wordPos.size());
		}
	}

	if(randomEnable == true){
		getRandomOrder();
	}else{
		for(int i=0;i<numOfNails;i++)
			//order[i] = i+1;
			order[i] = i;
	}

	for(int i=0;i<numOfNails;i++)
		nailLayout->addWidget(nails[order[i]]);
		
	setLayout(nailLayout);
}

/**********************************************************************************
 * WordLine::getRandomOrder -- 产生一个随机数组用于打乱nails[]的顺序              *
 *                                                                                *
 * INPUT: none                                                                    *
 *                                                                                *
 * OUTPUT: none                                                                   *
 *                                                                                *
 * WARNINGS: sys目录要处于可执行文件的上一级目录                                  *
 *                                                                                *
 * HISTORY:                                                                       *
 *   2020/12/26 LBW : Created.                                                    *
 *================================================================================*/

void WordLine::getRandomOrder()
{
	QSqlDatabase db;
	if(QSqlDatabase::contains("random_connection"))
		db = QSqlDatabase::database("random_connection");
	else
		db = QSqlDatabase::addDatabase("QSQLITE","random_connection");
	db.setDatabaseName("../sys/random.db");

	if(!db.open())
		qDebug() << db.lastError().text();
	
	QSqlQuery query(db);
	
	query.exec(QString("select count(*) from random where total = %0").arg(numOfNails));
	query.next();

	//qDebug() << "numOfNails is" << numOfNails;
	
	qsrand(QTime(0,0,0).msecsTo(QTime::currentTime()));
	int randomFactor = qrand()%query.value(0).toInt();
	//qDebug() << QString("random factor of %1 nails is ").arg(numOfNails) << randomFactor;

	query.exec(QString("select * from random where total = %1 limit %2,1").arg(numOfNails).arg(QString::number(randomFactor)));
	query.next();
	for(int i=0;i<numOfNails;i++){
		//order[i] = query.value(QString::number(i+1)).toInt();
		order[i] = query.value(QString::number(i)).toInt();
	}
}

/**********************************************************************************
 * WordLine::paintEvent -- Qt中改变部件样式需要定义的事件                         *
 *                                                                                *
 * INPUT: QPainEvent *                                                            *
 *                                                                                *
 * OUTPUT: none                                                                   *
 *                                                                                *
 * WARNINGS: none                                                                 *
 *                                                                                *
 * HISTORY:                                                                       *
 *   2020/12/26 LBW : Created.                                                    *
 *================================================================================*/

void WordLine::paintEvent(QPaintEvent *)
{
	QStyleOption opt;
	opt.init(this);
	QPainter p(this);
	style()->drawPrimitive(QStyle::PE_Widget,&opt,&p,this);
}

/**********************************************************************************
 * WordLine::nailAt -- 返回一个指向指定nail的指针                                 *
 *                                                                                *
 * INPUT: nailPos -- nail的位置                                                   *
 *                                                                                *
 * OUTPUT: nails[nailPos] -- 指向该nail的指针                                     *
 *                                                                                *
 * WARNINGS: none                                                                 *
 *                                                                                *
 * HISTORY:                                                                       *
 *   2020/12/26 LBW : Created.                                                    *
 *================================================================================*/

Nail* WordLine::nailAt(int nailPos) const{
	return nails[nailPos];
}

/**********************************************************************************
 * WordLine::getNumOfNails -- 返回需要记忆的单词+干扰词的数量                     *
 *                                                                                *
 * INPUT: none                                                                    *
 *                                                                                *
 * OUTPUT: numOfNails -- nail的数量                                               *
 *                                                                                *
 * WARNINGS: none                                                                 *
 *                                                                                *
 * HISTORY:                                                                       *
 *   2020/12/26 LBW : Created.                                                    *
 *================================================================================*/

int WordLine::getNumOfNails() const{
	return numOfNails;
}
